/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2009，所有权利保留。
 * 
 * 项目名：	rumba-web
 * 文件名：	RButton.java
 * 模块说明：	
 * 修改历史：
 * Jan 8, 2009 - lxm - 创建。
 */
package com.hd123.rumba.gwt.widget2.client.button;

import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.CustomButton;
import com.hd123.rumba.gwt.widget2.client.action.IsRActionControl;
import com.hd123.rumba.gwt.widget2.client.action.RAction;
import com.hd123.rumba.gwt.widget2.client.hotkey.HasRHotKey;
import com.hd123.rumba.gwt.widget2.client.hotkey.RHotKey;
import com.hd123.rumba.gwt.widget2.client.hotkey.RHotKeyManager;
import com.hd123.rumba.gwt.widget2.client.misc.RImageLocation;

/**
 * 符合Rumba标准的按钮控件。
 * <p>
 * 
 * <b>CSS Style Rules</b> <ol type=disc>
 * <li>.rb-Button[-up|-up-hovering|-up-disabled] {.html-face}
 * </ol>
 * 
 * TODO: 提供按钮被按下时显示样式变化，以提高“手感”。
 * 
 * @author lxm
 * 
 */
@SuppressWarnings("deprecation")
public class RButton extends CustomButton implements IsRActionControl, IsRButton, HasRHotKey {

  private static final String STYLENAME_DEFAULT = "rb-Button";

  /**
   * 创建对象实例。
   */
  public RButton() {
    super();
    setStyleName(STYLENAME_DEFAULT);
    addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        if (action == null)
          return;
        action.fireClick();
      }
    });
  }

  /**
   * 创建对象实例。
   * 
   * @param action
   *          指定对应的动作控件对象。
   */
  public RButton(RAction action) {
    this();
    setAction(action);
  }

  public RButton(String text) {
    this();
    setText(text);
  }

  /**
   * @deprecated 被{@link #RButton(String, ClickHandler)}替代。
   */
  public RButton(String text, ClickListener listener) {
    this(text);
    addClickListener(listener);
  }

  public RButton(String text, ClickHandler handler) {
    this(text);
    addClickHandler(handler);
  }

  private String caption;
  private RImageLocation icon;
  private RImageLocation hoveringIcon;
  private RImageLocation disabledIcon;
  private boolean showIcon = true;
  private boolean showText = true;
  private String title;
  private RAction action;
  private RHotKey hotKey;

  public String getText() {
    return caption;
  }

  public void setText(String text) {
    caption = text;
    refresh();
  }

  public String getHTML() {
    return getText();
  }

  public void setHTML(String html) {
    setText(html);
  }

  /** 图标。 */
  public RImageLocation getIcon() {
    return icon;
  }

  /** 图标。 */
  public void setIcon(RImageLocation icon) {
    this.icon = icon;
    refresh();
  }

  /** 当鼠标移动到控件上方的时候显示的图标。null表示显示{@link #icon}。 */
  public RImageLocation getHoveringIcon() {
    return hoveringIcon;
  }

  /** 当鼠标移动到控件上方的时候显示的图标。null表示显示{@link #icon}。 */
  public void setHoveringIcon(RImageLocation hoveringIcon) {
    this.hoveringIcon = hoveringIcon;
    refreshHoveringFace();
  }

  /** 当不可用的时候显示的图标。 null表示显示{@link #icon}。 */
  public RImageLocation getDisabledIcon() {
    return disabledIcon;
  }

  /** 当不可用的时候显示的图标。 null表示显示{@link #icon}。 */
  public void setDisabledIcon(RImageLocation disabledIcon) {
    this.disabledIcon = disabledIcon;
    refreshDisabledFace();
  }

  public boolean isShowIcon() {
    return showIcon;
  }

  public void setShowIcon(boolean showIcon) {
    this.showIcon = showIcon;
    if (!this.showIcon && !showText)
      showText = true;
    refresh();
  }

  public boolean isShowText() {
    return showText;
  }

  public void setShowText(boolean showText) {
    this.showText = showText;
    if (!this.showText && !showIcon)
      showIcon = true;
    refresh();
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
    refreshTitle();
  }

  /**
   * 根据title和热键刷新提示信息
   * 
   */
  protected void refreshTitle() {
    StringBuffer s = new StringBuffer();
    if (title != null)
      s.append(title);

    RHotKey hKey = null;
    if (hotKey != null)
      hKey = hotKey;
    else if (action != null)
      hKey = action.getHotKey();
    if (hKey != null) {
      if (s.length() > 0)
        s.append(" ");
      s.append(hKey.toString());
    }

    super.setTitle(s.toString());
  }

  public RAction getAction() {
    return action;
  }

  public void setAction(RAction action) {
    if (action == null) {
      if (this.action != null)
        this.action.removeControl(this);
    }

    this.action = action;

    if (this.action != null) {
      if (this.action.containsControl(this))
        return;
      this.action.addControl(this);
    }
  }

  public void applyAction() {
    if (action == null)
      return;
    setHTML(action.getCaption());
    setTitle(action.getTitle());
    setEnabled(action.isEnabled());

    icon = action.getIcon();
    hoveringIcon = action.getHoveringIcon();
    disabledIcon = action.getDisabledIcon();
    refresh();
  }

  public RHotKey getHotKey() {
    return hotKey;
  }

  public void setHotKey(RHotKey hotKey) {
    if (this.hotKey == hotKey)
      return;

    this.hotKey = hotKey;
    RHotKeyManager.remove(this);
    if (this.hotKey != null) {
      RHotKeyManager.add(this.hotKey, this, new Command() {
        public void execute() {
          click();
        }
      });
    }

    refreshTitle();
  }

  public void clearHotKey() {
    setHotKey(null);
  }

  // protected void onClick() {
  // setDown(false);
  // super.onClick();
  // }

  // protected void onClickCancel() {
  // setDown(false);
  // }

  // protected void onClickStart() {
  // setDown(true);
  // }

  /**
   * 模拟按钮点击动作
   * 
   */
  public void click() {
    DomEvent.fireNativeEvent(Document.get().createClickEvent(0, 0, 0, 0, 0, false, false, false,
        false), this);
  }

  private void refresh() {
    refreshUpFace();
    refreshHoveringFace();
    refreshDisabledFace();
  }

  private void refreshUpFace() {
    StringBuffer sb = new StringBuffer();
    if (showIcon && icon != null)
      sb.append(icon.toHTML());
    if (showText) {
      if (sb.length() > 0)
        sb.append(" ");
      sb.append(caption);
    }
    getUpFace().setHTML(sb.toString());
  }

  private void refreshHoveringFace() {
    if (hoveringIcon == null)
      return;

    StringBuffer sb = new StringBuffer();
    if (showIcon) {
      RImageLocation icon2 = hoveringIcon != null ? hoveringIcon : icon;
      if (icon2 != null)
        sb.append(icon2.toHTML());
    }
    if (showText) {
      if (sb.length() > 0)
        sb.append(" ");
      sb.append(caption);
    }
    getUpHoveringFace().setHTML(sb.toString());
  }

  private void refreshDisabledFace() {
    StringBuffer sb = new StringBuffer();
    if (showIcon) {
      RImageLocation icon2 = disabledIcon != null ? disabledIcon : icon;
      if (icon2 != null)
        sb.append(icon2.toHTML());
    }
    if (showText) {
      if (sb.length() > 0)
        sb.append(" ");
      sb.append(caption);
    }
    getUpDisabledFace().setHTML(sb.toString());
  }

}
